package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.sky.dto.GoodsSalesDTO;
import com.sky.dto.ReportDto;
import com.sky.entity.Orders;
import com.sky.entity.User;
import com.sky.mapper.ReportMapper;
import com.sky.mapper.UserMapper;
import com.sky.result.Result;
import com.sky.service.ReportService;
import com.sky.service.WorkSpaceService;
import com.sky.vo.BusinessDataVO;
import com.sky.vo.SalesTop10ReportVO;
import com.sky.vo.TurnoverReportVO;
import com.sky.vo.UserReportVO;
import io.swagger.models.auth.In;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName: ReportServiceImpl
 * @Author: YuanDing
 * @Date: 2024/2/9 16:27
 * @Description:
 */


@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    private ReportMapper reportMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private WorkSpaceService workSpaceService;

    /**
     * 导出30天运营数据
     * @param httpServletResponse
     */
    @Override
    public void export(HttpServletResponse httpServletResponse) {
        LocalDate begin = LocalDate.now().minusDays(30);
        LocalDate end = LocalDate.now().minusDays(1);
        // 获取近30天工作数据
        BusinessDataVO businessData = (BusinessDataVO) workSpaceService.businessData(begin, end).getData();

        InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
        try {
            // 创建excel实例

            XSSFWorkbook sheets = new XSSFWorkbook(in);

            // 写入数据
            XSSFSheet sheet1 = sheets.getSheet("Sheet1");

            sheet1.getRow(1).getCell(1).setCellValue("时间：" + begin.toString() + "-" + end.toString());

            // 设置概览数据
            XSSFRow row3 = sheet1.getRow(3);
            row3.getCell(2).setCellValue(businessData.getTurnover());
            row3.getCell(4).setCellValue(businessData.getOrderCompletionRate());
            row3.getCell(6).setCellValue(businessData.getNewUsers());

            XSSFRow row4 = sheet1.getRow(4);
            row4.getCell(2).setCellValue(businessData.getValidOrderCount());
            row4.getCell(4).setCellValue(businessData.getUnitPrice());

            // 设置明细数据
            for (int i = 0; i < 30; i++) {
                LocalDateTime beginTime = begin.atStartOfDay();
                LocalDateTime endTime = begin.atTime(LocalTime.MAX);
                BusinessDataVO data = (BusinessDataVO) workSpaceService.businessData(begin, begin).getData();

                XSSFRow row = sheet1.getRow(7 + i);
                row.getCell(1).setCellValue(begin.toString());
                row.getCell(2).setCellValue(data.getTurnover());
                row.getCell(3).setCellValue(data.getValidOrderCount());
                row.getCell(4).setCellValue(data.getOrderCompletionRate());
                row.getCell(5).setCellValue(data.getUnitPrice());
                row.getCell(6).setCellValue(data.getNewUsers());
                begin = begin.plusDays(1);
            }

            ServletOutputStream outputStream = httpServletResponse.getOutputStream();
            sheets.write(outputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Override
    public Result userStatistics(ReportDto reportDto) {
        List<LocalDate> dateList = getDateList(reportDto.getBegin(), reportDto.getEnd());

        List<Integer> newUserCountList = new ArrayList<>();
        List<Integer> userCountList = new ArrayList<>();

        for (LocalDate date :  dateList) {
            HashMap<String, LocalDateTime> map = new HashMap<>();
            map.put("end" , date.atTime(LocalTime.MAX));
            userCountList.add(userMapper.selectByMap(map));
            map.put("begin", date.atStartOfDay());
            newUserCountList.add(userMapper.selectByMap(map));
        }
        String newUserCountListString = StringUtils.join(newUserCountList, ",");
        String userCountListString = StringUtils.join(userCountList, ",");
        String dateListString = StringUtils.join(dateList, ",");

        return Result.success(UserReportVO.builder()
                .newUserList(newUserCountListString)
                .totalUserList(userCountListString)
                .dateList(dateListString)
                .build());
    }

    /**
     * 销量top
     * @param reportDto
     * @return
     */
    @Override
    public Result top(ReportDto reportDto) {
        List<GoodsSalesDTO> goodsSalesDTOList = reportMapper.countDishTop(reportDto.getBegin().atStartOfDay() , reportDto.getEnd().atTime(LocalTime.MAX));
        List<String> nameList = goodsSalesDTOList.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList());
        List<Integer> numberList = goodsSalesDTOList.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList());
        String nameListString = StringUtils.join(nameList, ",");
        String numberListString = StringUtils.join(numberList, ",");
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("numberList" , numberListString);
        hashMap.put("nameList" , nameListString);
        return Result.success(hashMap);
    }

    /**
     * 营业额统计
     * @param begin 开始日期
     * @param end 结束日期
     * @return
     */
    @Override
    public Result turnoverStatistics(LocalDate begin, LocalDate end) {
        TurnoverReportVO reportVO = new TurnoverReportVO();
        // 日期列表
        String dateListWithString = getDateListWithString(begin , end);
        // 营业额列表
        ArrayList<Integer> turnoverList = new ArrayList<>();
        List<LocalDate> dateList = getDateList(begin , end);
        for(LocalDate date : dateList) {
            Integer result = reportMapper.countTurnoverByDay(date.atStartOfDay(), date.atTime(LocalTime.MAX));
            if (result != null) {
                turnoverList.add(result);
            } else {
              turnoverList.add(0);
            }
        }
        reportVO.setDateList(dateListWithString);
        String turnoverString = StringUtils.join(turnoverList, ",");
        reportVO.setTurnoverList(turnoverString);
        return Result.success(reportVO);
    }

    /**
     * 订单统计相关
     * @return
     */
    @Override
    public Result ordersStatistics(LocalDate beginDate , LocalDate endDate) {
        HashMap<Object, Object> map = new HashMap<>();
        Integer validOrderCount = reportMapper.validOrderCountByCondition(beginDate.atStartOfDay() , endDate.atTime(LocalTime.MAX));
        List<Orders> ordersList = reportMapper.selectOrderByCondition(beginDate.atStartOfDay() , endDate.atTime(LocalTime.MAX));

        // 有效订单数列表
        ArrayList<Object> validOrderList = new ArrayList<>();
        // 订单总数列表
        ArrayList<Object> allOrderList = new ArrayList<>();

        List<LocalDate> dateList = getDateList(beginDate, endDate);
        for(LocalDate date : dateList) {
            validOrderList.add(reportMapper.countValidOrderByDay(date.atStartOfDay() , date.atTime(LocalTime.MAX)));
            allOrderList.add(reportMapper.countOrderByDay(date.atStartOfDay() , date.atTime(LocalTime.MAX)));
        }

        String validOrderCountList = StringUtils.join(validOrderList, ",");
        String orderCountList = StringUtils.join(allOrderList, ",");


        String dateListWithString = getDateListWithString(beginDate , endDate);
        map.put("orderCompletionRate" ,  (double)validOrderCount / ordersList.size());
        map.put("dateList" ,  dateListWithString);
        map.put("validOrderCount" ,  validOrderCount);
        map.put("totalOrderCount" ,  ordersList.size());
        map.put("validOrderCountList" ,  validOrderCountList);
        map.put("orderCountList" ,  orderCountList);



        return Result.success(map);
    }

    /**
     * 获取以字符串分隔的日期列表
     * @param beginDate
     * @param endDate
     * @return
     */
    private String getDateListWithString(LocalDate beginDate , LocalDate endDate) {
        List<LocalDate> dateList = getDateList(beginDate, endDate);
        return StringUtils.join(dateList, ",");
    }

    /**
     * 获取日期集合
     * @return
     */
    private List<LocalDate> getDateList(LocalDate beginDate , LocalDate endDate) {
        ArrayList<LocalDate> dateList = new ArrayList<>();
        dateList.add(beginDate);
        LocalDate startDate = beginDate;
        while (!startDate.equals(endDate)) {
            startDate = startDate.plusDays(1);
            dateList.add(startDate);
        }
        return dateList;
    }

}
